package org.cable.account.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author hsj
 * @date 2023/10/26 10:45
 */
@Configuration
@EnableAsync
public class ThreadPoolTaskConfig {


    @Bean("threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){

        ThreadPoolTaskExecutor executor  =  new ThreadPoolTaskExecutor();
        /**核心线程数*/
        executor.setCorePoolSize(8);
        /**阻塞队列的最大值,当核心线程数达到最大值时,会放在阻塞队列中*/
        executor.setQueueCapacity(124);

        /**任务队列已满时,线程池会创建新的线程来处理任务*/
        executor.setMaxPoolSize(64);

        /**允许线程空闲时间60秒，当maxPoolSize的线程在空闲时间到达的时候销毁*/
        executor.setKeepAliveSeconds(30);

        executor.setThreadNamePrefix("账户体系自定义线程池");

        /**拒绝策略
         * CallerRunsPolicy()：交由调⽤⽅线程运⾏，⽐如main 线程；如果添加到线程池失败，那么主线程会⾃⼰去执⾏该任务，不会等待线程池中的线程去执⾏
         *AbortPolicy()：该策略是线程池的默认策略，如果线程池队列满了丢掉这个任务并且抛出RejectedExecutionException异常
         *DiscardPolicy()：如果线程池队列满了，会直接丢掉这个任务并且不会有任何异常
         * DiscardOldestPolicy(): 丢弃队列中最⽼的任务，队列满了，会将最早进⼊队列的任务删掉腾出空间，再尝试加⼊队列
         * */
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());

        executor.initialize();

        return executor;
    }
}
